﻿using System;
using System.Net.Sockets;

namespace Tensop.Net.Tcp
{
    public class Client : IDisposable
    {

        internal static DateTime             m_DefaultTime;
        //

        private Socket                      m_Client;//绑定之后的客户端连接
        private SocketAsyncEventArgs        m_Read;//用于读取数据的异步Socket对象
        private SocketAsyncEventArgs        m_Write;//用于发送数据的异步Socket对象
        private bool                        m_Connected;//指示当前客户端的连接状态
        private byte[]                      m_ReadBuffer;//读取缓冲区
        private byte[]                      m_SendBuffer;//写入缓冲区
        private int                         m_Handle;//当前连接的句柄
        private DateTime                    m_StartTime;
        private DateTime                    m_EndTime;


        private EventHandler<SocketAsyncEventArgs>      IOCompleted;//完成事件处理

        internal ServerReceiveEventArgs EventArgs { get; set; }
        internal int ContentLength { get; set; }

        internal Socket Base { get => m_Client; set => m_Client = value; }
        internal SocketAsyncEventArgs Read { get => m_Read; }
        internal SocketAsyncEventArgs Write { get => m_Write; }
        internal DateTime StartTime { get => m_StartTime; set => m_StartTime = value; }
        internal DateTime EndTime { get => m_EndTime; set => m_EndTime = value; }
        internal int BufferSize { get => m_ReadBuffer.Length; }
        internal bool Connected { get => m_Connected; set => m_Connected = value; }

        public int Id { get => m_Handle; }
        public byte[] SendBuffer { get; set; }
        public object UserToken { get; set; }

        static Client()
        {
            m_DefaultTime = DateTime.Now;
        }

        public Client(int handle, int size, EventHandler<SocketAsyncEventArgs> e)
        {

            m_Read = new SocketAsyncEventArgs();
            m_Write = new SocketAsyncEventArgs();
            m_ReadBuffer = new byte[ size ];
            m_SendBuffer = new byte[ size ];

            m_Handle = handle;
            m_Connected = false;

            m_Read.UserToken = m_Write.UserToken = this;
            IOCompleted = e;

            m_Read.Completed += IOCompleted;
            m_Write.Completed += IOCompleted;
            m_Read.SetBuffer( m_ReadBuffer, 0, m_ReadBuffer.Length );
            m_Write.SetBuffer( m_SendBuffer, 0, m_SendBuffer.Length );
            ContentLength = -1;
        }

        public void Dispose()
        {
            m_Read.Completed -= IOCompleted;
            m_Write.Completed -= IOCompleted;

            try
            { m_Client.Shutdown( SocketShutdown.Both ); }
            catch { }
            finally
            {
                m_Read.Dispose();
                m_Write.Dispose();

            }
            GC.SuppressFinalize( this );
        }
    }
}
